import pandas as pd
import numpy as np
import random
from datetime import datetime, timedelta


def generate_property_insurance_data(num_records=1000):
    """
    生成财产保险成本费用的模拟数据

    参数:
        num_records: 要生成的记录数量

    返回:
        DataFrame: 包含财产保险成本费用数据的DataFrame
    """
    # 设置随机种子，确保结果可重现
    np.random.seed(42)
    random.seed(42)

    # 定义可能的财产类型及其相关参数
    property_types = [
        {"type": "住宅", "value_range": (500000, 5000000), "premium_rate_range": (0.001, 0.003)},
        {"type": "商业建筑", "value_range": (2000000, 20000000), "premium_rate_range": (0.0015, 0.004)},
        {"type": "工业厂房", "value_range": (5000000, 50000000), "premium_rate_range": (0.002, 0.005)},
        {"type": "仓库", "value_range": (1000000, 10000000), "premium_rate_range": (0.0018, 0.0045)},
        {"type": "办公楼", "value_range": (3000000, 30000000), "premium_rate_range": (0.0016, 0.0035)}
    ]

    # 生成基础数据
    data = []
    for _ in range(num_records):
        # 随机选择财产类型
        prop_type_info = random.choice(property_types)
        prop_type = prop_type_info["type"]

        # 生成财产价值（服从对数正态分布，更符合实际资产价值分布）
        value_mean = np.log(np.mean(prop_type_info["value_range"]))
        value_std = 0.5  # 控制分布的离散程度
        prop_value = int(np.random.lognormal(value_mean, value_std))
        # 确保价值在指定范围内
        prop_value = max(prop_type_info["value_range"][0],
                         min(prop_type_info["value_range"][1], prop_value))

        # 生成保险期限（月）
        term_months = random.choice([6, 12, 24, 36])

        # 生成保险费率
        premium_rate = np.random.uniform(
            prop_type_info["premium_rate_range"][0],
            prop_type_info["premium_rate_range"][1]
        )

        # 计算基础保费
        base_premium = prop_value * premium_rate * (term_months / 12)

        # 添加一些调整因子（如安全设施、位置风险等）
        safety_factor = np.random.uniform(0.8, 1.2)  # 安全设施好则降低保费
        location_risk = np.random.uniform(0.9, 1.3)  # 位置风险高则增加保费
        claim_history = np.random.uniform(0.85, 1.15)  # 索赔历史好则降低保费

        # 计算最终保费
        final_premium = base_premium * safety_factor * location_risk * claim_history
        final_premium = round(final_premium, 2)

        # 计算免赔额（通常为财产价值的一定比例）
        deductible_ratio = np.random.choice([0.005, 0.01, 0.02, 0.03])
        deductible = int(prop_value * deductible_ratio)

        # 生成保险开始日期
        start_date = datetime.now() + timedelta(days=random.randint(-365, 30))
        start_date_str = start_date.strftime("%Y-%m-%d")

        # 生成保险结束日期
        end_date = start_date + timedelta(days=int(term_months * 30.44))
        end_date_str = end_date.strftime("%Y-%m-%d")

        # 生成保险公司
        insurance_company = random.choice([
            "平安保险", "中国人寿", "太平洋保险", "中国人保",
            "新华保险", "泰康保险", "阳光保险", "大地保险"
        ])

        # 生成是否有附加险
        has_additional_coverage = random.choice([True, False])

        # 如果有附加险，计算附加费用
        additional_cost = 0
        if has_additional_coverage:
            additional_cost = round(final_premium * np.random.uniform(0.1, 0.3), 2)

        # 总费用
        total_cost = final_premium + additional_cost

        # 添加到数据列表
        data.append({
            "财产ID": f"PROP{random.randint(100000, 999999)}",
            "财产类型": prop_type,
            "财产价值(元)": prop_value,
            "保险开始日期": start_date_str,
            "保险结束日期": end_date_str,
            "保险期限(月)": term_months,
            "基础保费(元)": round(base_premium, 2),
            "最终保费(元)": final_premium,
            "附加费用(元)": additional_cost,
            "总费用(元)": round(total_cost, 2),
            "免赔额(元)": deductible,
            "保险公司": insurance_company,
            "是否有附加险": "是" if has_additional_coverage else "否",
            "安全系数": round(safety_factor, 2),
            "位置风险系数": round(location_risk, 2),
            "索赔历史系数": round(claim_history, 2)
        })

    # 转换为DataFrame
    df = pd.DataFrame(data)

    # 调整列的顺序
    column_order = [
        "财产ID", "财产类型", "财产价值(元)", "保险开始日期", "保险结束日期",
        "保险期限(月)", "基础保费(元)", "最终保费(元)", "附加费用(元)",
        "总费用(元)", "免赔额(元)", "保险公司", "是否有附加险",
        "安全系数", "位置风险系数", "索赔历史系数"
    ]
    df = df[column_order]

    return df


if __name__ == "__main__":
    # 生成1000条财产保险数据
    insurance_data = generate_property_insurance_data(1000)

    # 显示前5条数据
    print("财产保险成本费用模拟数据（前5条）：")
    print(insurance_data.head())

    # 保存为CSV文件
    insurance_data.to_csv("property_insurance_costs.csv", index=False, encoding="utf-8-sig")
    print("\n数据已保存到 property_insurance_costs.csv 文件")

    # 打印一些统计信息
    print("\n数据统计信息：")
    print(f"总记录数：{len(insurance_data)}")
    print("\n按财产类型统计：")
    print(insurance_data["财产类型"].value_counts())
    print("\n总费用统计：")
    print(insurance_data["总费用(元)"].describe().round(2))
